# -*- coding: utf-8 -*-
""" A class to browse a file. If it's **NOT** a text file do nothing

    :Author:
      - 20091202-20100321 Nicola Creati
      - 20111202-20120214 Roberto Vidmar

    :Revision:  $Revision: 52 $
                $Date: 2012-11-12 09:07:15 +0000 (Mon, 12 Nov 2012) $

    :Copyright: 2011-2012
                Nicola Creati <ncreati@inogs.it>
                Roberto Vidmar <rvidmar@inogs.it>

    :License: MIT/X11 License (see :download:`license.txt
                               <../../license.txt>`)
"""

from string import maketrans
from qtCompat import QtCore, QtGui

def isText(s, threshold=0.30):
  """ Return True if s is a Text string.

      If more than 30% non-text characters, then this is considered a binary
      string

    :param s: string to test
    :type s: string
    :param threshold: threshold to make the decision
    :type threshold: float [0, 1], no check
    :returns: True if s Dacontains pure Text
    :rtype: bool
    :raises:
  """

  text_characters = "".join(map(chr, range(32, 127)) + list("\n\r\t\b"))
  null_trans = maketrans("", "")

  if "\0" in s:
    return False

  if not s:  # Empty files are considered text
    return True

  # Get the non-text characters (maps a character to itself then
  # use the 'remove' option to get rid of the text characters.)
  t = s.translate(null_trans, text_characters)

  # If more than 30% non-text characters, then
  # this is considered a binary string
  return len(t)/len(s) <= threshold

def isTextFile(filename, blocksize=512):
  """ Return True if filename is a Text file.

    :param filename: pathname
    :type filename: string
    :param blocksize: number of bytes to read to guess the type
    :type blocksize: int
    :returns: True if filename is a Text file
    :rtype: bool
    :raises:
  """
  return isText(open(filename).read(blocksize))

class FileBrowser(QtGui.QMainWindow):
  def __init__(self, parent=None, path=None):
    """ Create a new instance of the FileBrowser.

    :param parent: parent widget
    :type parent: QtGui widget
    :param path: pathname of the file to browse
    :type path: string, unicode
    :raises:
    """
    super(FileBrowser, self).__init__(parent)

    self.editor = QtGui.QTextEdit()
    self.editor.setReadOnly(True)
    self.openFile(path)
    self.highlighter = Highlighter(self.editor.document())
    self.setCentralWidget(self.editor)

  def openFile(self, pn=None):
    """ Load pn file content into widget.

    :param pn: pathname
    :type pn:  string or unicode
    :raises:
    """
    if pn:
      inFile = QtCore.QFile(pn)
      if inFile.open(QtCore.QFile.ReadOnly | QtCore.QFile.Text):
        if isTextFile(pn):
          font = QtGui.QFont("Courier New", 11, QtGui.QFont.DemiBold)
          self.editor.setCurrentFont(font)
          self.editor.setPlainText(unicode(inFile.readAll()))

class Highlighter(QtGui.QSyntaxHighlighter):
  KEYWORDS = (
    "description",
    "samples",
    "lines",
    "bands",
    "header offset",
    "file type",
    "data type",
    "interleave",
    "sensor type",
    "byte order",
    "map info",
    "default bands",
    "wavelength units",
    "band names",
    "fwhm",
    "vimg",
    "wavelength",
    "sensorid",
    "radcorr version",
    "acquisition date",
    "GPS Start Time",
    "GPS Stop Time",
    "GPS location",
    "x start",
    "y start",
    "fps",
    "binning",
    "vroi",
    "hroi",
    "tint",
    "himg",
    "fodis",
    "errors",
    "Wavelength")

  def __init__(self, parent=None):
    """ Create a new instance of the Highlighter.

    :param parent: parent widget
    :type parent: QtGui widget
    :raises:
    """
    super(Highlighter, self).__init__(parent)

    keywordFormat = QtGui.QTextCharFormat()
    keywordFormat.setForeground(QtCore.Qt.darkBlue)
    keywordFormat.setFontWeight(QtGui.QFont.Bold)

    keywordPatterns = ["\\b%s\\b" % k for k in self.KEYWORDS]

    self.highlightingRules = [(QtCore.QRegExp(pattern), keywordFormat)
      for pattern in keywordPatterns]

  def highlightBlock(self, text):
    for pattern, fmt in self.highlightingRules:
      expression = QtCore.QRegExp(pattern)
      index = expression.indexIn(text)
      while index >= 0:
        length = expression.matchedLength()
        self.setFormat(index, length, fmt)
        index = expression.indexIn(text, index + length)

    self.setCurrentBlockState(0)

#===============================================================================
if __name__ == '__main__':

  import sys
  import signal
  signal.signal(signal.SIGINT, signal.SIG_DFL)

  app = QtGui.QApplication(sys.argv)
  window = FileBrowser(path=__file__)
  window.resize(640, 480)
  window.show()
  sys.exit(app.exec_())
